home *** CD-ROM | disk | FTP | other *** search
/ Amiga Collections: Taifun / Taifun 112 (1989-11-15)(Ossowski, Stefan)(DE)(PD).zip / Taifun 112 (1989-11-15)(Ossowski, Stefan)(DE)(PD).adf / C64Emul / src / main.c < prev    next >
C/C++ Source or Header  |  1989-07-02  |  7KB  |  391 lines

  1. /*
  2.  *        Commodore 64 Spoof Emulator (C) Eddy Carroll, 1st April 1988
  3.  *
  4.  * Module: MAIN.C
  5.  *
  6.  * This module is the mainline - it handles the input loop and command
  7.  * interpretation logic.
  8.  *
  9.  */
  10.  
  11. #include <exec/types.h>
  12. #include <exec/io.h>
  13. #include <intuition/intuition.h>
  14. #include <proto/exec.h>
  15. #include <proto/intuition.h>
  16. #include <proto/graphics.h>
  17. #include "screen.h"
  18. #include "commands.h"
  19.  
  20. #define DEL '\177'
  21. /* 
  22.  *  Defining the following functions here stops them from being pulled into
  23.  *  the program from the Lattice library when we link.
  24.  */
  25.  
  26. int chkabort() {return(0);}
  27. void MemCleanup() {}
  28.  
  29. /*
  30.  *    Global references
  31.  */
  32.  
  33. extern struct Menu mymenus;
  34. extern struct IntuiText mytext[];
  35.  
  36. extern struct commandlist command[];    /* Commands & Responses */
  37. extern char *errormsg[];                /* List of error msgs    */
  38. extern int  MAXCOMMANDS;                /* Number of commands    */
  39. extern int  MAXERRORS;                    /* Number of messages    */
  40. extern char *STARTUP;                    /* Startup message        */
  41. extern char *ABOUT;                        /* "About..." message    */
  42. extern char *READY;                        /* Ready prompt            */
  43.  
  44. /*
  45.  * Executes one of the menu commands
  46.  *
  47.  */
  48.  
  49. void domenu(opt)
  50. int opt;
  51. {
  52.     CURSOROFF;
  53.  
  54.     switch (opt) {
  55.  
  56.     case M_ABOUT:
  57.         clearscreen();
  58.         if (titlebar) printchar('\r'); /* Skip past title bar if on */
  59.         printmess(ABOUT);
  60.         printmess(READY);
  61.         break;
  62.  
  63.     case M_TITLE:
  64.         titlebar = !titlebar;
  65.         ClearMenuStrip(mywin);
  66.         mytext[1].IText = titlebar ? " Hide Title" : " Show Title";
  67.         SetMenuStrip(mywin,&mymenus);
  68.         ShowTitle(myscreen, titlebar);
  69.         break;
  70.  
  71.     case M_QUIT:
  72.         cleanup(0);
  73.         break;
  74.  
  75.     }
  76. }
  77.  
  78. /*
  79.  * Returns a random number in range 0..range-1.
  80.  *
  81.  */
  82.  
  83. int random(range)
  84. int range;
  85. {
  86.     LONG seconds,micros;
  87.     CurrentTime(&seconds,µs);
  88.     return (micros % range);
  89. }
  90.  
  91.  
  92. /*
  93.  * Reads current line from screen into string, stripping off any extra
  94.  * leading or trailing spaces.
  95.  *
  96.  */
  97.  
  98. void getcommand(s)
  99. char *s;
  100. {
  101.     int i = 0, j = 39;
  102.     char *p; 
  103.     p = screen[cursory];
  104.     while (p[i] == ' ' && i < 40)
  105.         i++;
  106.     if (i == 40) {
  107.         *s = '\0';
  108.         return;
  109.     } 
  110.  
  111.     while (p[j] == ' ')
  112.         j--;
  113.     while (i <= j) {
  114.         *s++ = toupper(p[i]);
  115.         i++;
  116.     }
  117.     *s = '\0';
  118. }
  119.  
  120.  
  121. /*
  122.  * Returns TRUE if the first n chars of the two strings are equal, else
  123.  * returns FALSE
  124.  *
  125.  */
  126.  
  127. int match(s1,s2,n)
  128. char *s1,*s2;
  129. int n;
  130. {
  131.     while (*s1++ == *s2++ && n)
  132.         n--;
  133.     return (!n);
  134. }
  135.  
  136.  
  137. /*
  138.  * Initialises error messages to be in random order.
  139.  *
  140.  */
  141.  
  142. void initerror()
  143. {
  144.     int i, x, y;
  145.     char *p;
  146.  
  147.     for (i = 0; i < MAXERRORS; i++) {
  148.         x = random(MAXERRORS);
  149.         y = MAXERRORS - 1 - random(MAXERRORS);
  150.         p = errormsg[x];
  151.         errormsg[x] = errormsg[y];
  152.         errormsg[y] = p;
  153.     }
  154. }
  155.  
  156.  
  157. /*
  158.  * Prints a suitable response for command in string s. If a match is found
  159.  * in the command list, then a reponse appropriate to that command is
  160.  * printed, else one of the standard error messages is printed.
  161.  *
  162.  */
  163.  
  164. void docommand(s)
  165. char *s;
  166. {
  167.     static int curerr = 0;
  168.     int i = 1, k = -1, x, y;
  169.     char *p;
  170.     struct commandlist *com;
  171.  
  172.     if (*s >= '0' && *s <= '9')
  173.         k = 0;
  174.     else {
  175.         while (i < MAXCOMMANDS && k < 0) {
  176.             if (match(command[i].asc,s,command[i].len))
  177.                 k = i; 
  178.             i++;
  179.         }
  180.     }
  181.  
  182.     printchar('\r');
  183.     if (k >= 0) {
  184.         com = &command[k];
  185.         do {
  186.             com->num++;
  187.  
  188.             /* If we have printed all three messages once each, re-arrange    */
  189.             /* the order of them before we print them again to make it        */
  190.             /* seem random.                                                    */
  191.  
  192.             if (com->num >= MAXRESPONSE) {
  193.                 com->num = 0;
  194.                 x = random(MAXRESPONSE); y = random(MAXRESPONSE);
  195.                 p = com->response[x];
  196.                 com->response[x] = com->response[y];
  197.                 com->response[y] = p;
  198.             }
  199.         } while ((p = com->response[com->num]) == NULL);
  200.         printmess(p);
  201.     } else {
  202.         printmess(errormsg[curerr]);
  203.         curerr++;
  204.         if (curerr >= MAXERRORS) {
  205.             curerr = 0;
  206.             initerror();
  207.         }
  208.     }
  209.  
  210.     printmess(READY);
  211. }
  212.  
  213.  
  214. /*
  215.  * Initialises the message headers to point to random messages
  216.  *
  217.  */
  218.  
  219. void initmess()
  220. {
  221.     int i;
  222.     for (i = 0; i < MAXCOMMANDS; i++)
  223.         command[i].num = random(3);
  224. }
  225.  
  226.  
  227. /*
  228.  *  Returns code for function key n, where n = 0..20
  229.  *  Returns 0 if no char equivalent. Also binds otherwise undefined
  230.  *  function keys to common commands recognised.
  231.  */
  232.  
  233. char fkey(n)
  234. int n;
  235. {
  236.     register char ch = 0;
  237.     switch (n) {
  238.  
  239.     case 9:        ch = C_HOME;
  240.                 break;
  241.     case 19:    ch = C_CLEAR;
  242.                 break;
  243.     case 20:     printmess("HELP");
  244.                 break;
  245.     default:    if (n >= 0 & n <= 19)
  246.                     printmess(command[n].asc);    /* Get command & print it */
  247.                 break;
  248.     }
  249.     return (ch);
  250. }
  251.  
  252. /*
  253.  * Converts code (an escape character) into one of the internal codes
  254.  * (or 0 if no corresponding code)
  255.  *
  256.  */
  257.  
  258. char convert(ch)
  259. char ch;
  260. {
  261.     switch (ch) {
  262.  
  263.     case 'A': ch = C_UP;        break;
  264.     case 'B': ch = C_DOWN;        break;
  265.     case 'C': ch = C_RIGHT;        break;
  266.     case 'D': ch = C_LEFT;        break;
  267.  
  268.     default:  ch = 0;
  269.     }
  270.  
  271.     return(ch);
  272. }
  273.  
  274. /*
  275.  * Mainline
  276.  *
  277.  */
  278.  
  279. void _main()
  280. {
  281.     LONG MenuNumber;
  282.     struct MenuItem *item;
  283.     register struct IntuiMessage *message;
  284.     register struct Message *conmessage;
  285.     int escape = 0;
  286.     LONG class;
  287.     USHORT code;
  288.     int time = 3, curstate = 0, fkeynum;
  289.     char s[50], ch;
  290.  
  291.  
  292.     titlebar = 0;    /* Initially hidden */
  293.     initscreen();
  294.     initmess();
  295.     initerror();
  296.     printmess(STARTUP);
  297.     printmess(READY);
  298.     CURSORON;
  299.  
  300.  
  301.     /* Main loop */
  302.  
  303. #define INTUIBITS    (1 << mywin->UserPort->mp_SigBit)
  304. #define CONSOLEBITS    (1 << ConReadPort->mp_SigBit)
  305.  
  306.     while (1) {
  307.  
  308.         /* Reset message pointers, just in case 2nd part of conditional */
  309.         /* && isn't executed. */
  310.         message    = NULL;
  311.         conmessage = NULL;
  312.  
  313.         while ((message = (struct IntuiMessage *)
  314.                     GetMsg(mywin->UserPort)) == NULL &&
  315.                 (conmessage = (struct Message *)
  316.                     GetMsg(ConReadPort)) == NULL)
  317.             Wait ( INTUIBITS | CONSOLEBITS);
  318.  
  319.  
  320.         if (message) {        /* Got an IntuiMessage */
  321.             class = message->Class;
  322.             code = message->Code;
  323.             ReplyMsg((struct Message *)message);
  324.  
  325.             switch (class) {
  326.  
  327.             case MENUPICK:
  328.                 MenuNumber = code;
  329.                 while (MenuNumber != MENUNULL) {
  330.                     item = (struct MenuItem *)ItemAddress(&mymenus,MenuNumber);
  331.                     code = item->Command;
  332.                     MenuNumber = item->NextSelect;
  333.                 }
  334.                 domenu(code);
  335.                 break;
  336.  
  337.             case INTUITICKS:
  338.                 if (time == 0) {
  339.                     curstate = 1 - curstate;
  340.                     if (curstate)
  341.                         CURSORON;
  342.                     else
  343.                         CURSOROFF;
  344.                     time = 3;
  345.                 } else --time;
  346.                 break;
  347.  
  348.             }
  349.         }
  350.  
  351.         if (conmessage) {        /* Character from console */
  352.             ch = *constring;
  353.             /* Retrieve char, then line up request for next char */
  354.             QueueRead(ConReadReq,constring);
  355.             if (ch == CSI)
  356.                 escape = 1, fkeynum = 0;
  357.             else {
  358.                 if (escape) {
  359.                     if (isdigit(ch))
  360.                         fkeynum = fkeynum * 10 + ch - '0', ch = 0;
  361.                     else if (ch == '?')
  362.                         fkeynum = 20, ch = 0;
  363.                     else if (ch == ' ')
  364.                         escape = 2, ch = 0;
  365.                     else {
  366.                         escape = 0;
  367.                         if (ch == '~')
  368.                             ch = fkey(fkeynum);
  369.                         else if (escape != 2)
  370.                             ch = convert(ch);
  371.                     }
  372.                 }
  373.                 CURSOROFF;
  374.                 if (ch == '\r') {
  375.                     getcommand(s);    /* Read command from screen */
  376.                     printchar(ch);
  377.                     if (*s)
  378.                         docommand(s);
  379.                 } else {
  380.                     if (ch == DEL)        /* If delete key (Ascii #127)    */
  381.                         ch = C_INSERT;    /* Make it act as insert        */
  382.                     printchar(ch);
  383.                 }
  384.                 CURSORON;
  385.                 time = 3;
  386.                 curstate = 1;
  387.             }
  388.         }
  389.     }
  390. }
  391.